/*******************************************************************************
 * Copyright (c) 2011-11-10 @author <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a>.
 * All rights reserved.
 *
 * Contributors:
 *     <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a> - initial API and implementation
 ******************************************************************************/
package com.redhat.auth.ejb.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.ejb.Remote;
import javax.ejb.Stateless;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.dayatang.domain.InstanceFactory;
import com.dayatang.querychannel.service.QueryChannelService;
import com.dayatang.querychannel.support.Page;
import com.redhat.auth.domain.FunctionEntity;
import com.redhat.auth.domain.Role;
import com.redhat.auth.domain.Role.Status;
import com.redhat.auth.ejb.RoleApplication;
import com.redhat.auth.ejb.vo.RoleVO;

/**
 * @author <a href="mailto:iffiff1@hotmail.com">Tyler Chen</a> 
 * @since 2011-11-10
 */
@Service("ramsRoleApplication")
@Stateless(name = "RoleApplicationBean")
@Remote(RoleApplication.class)
@javax.interceptor.Interceptors(SpringEJBIntercepter.class)
public class RoleApplicationImpl implements RoleApplication {
	// 查询通道
	protected static QueryChannelService queryChannel;

	protected static QueryChannelService queryChannel() {
		if (queryChannel == null) {
			queryChannel = InstanceFactory
					.getInstance(QueryChannelService.class);
		}
		return queryChannel;
	}

	public RoleVO createRole(RoleVO vo) {
		Role role = toRole(vo);
		return toRoleVO(role.create());
	}

	public void deleteRoleById(Long id) {
		Role r = Role.get(id);
		if (r != null) {
			r.delete();
		}
	}

	public Long getCount(RoleVO vo) {
		StringBuffer hql = new StringBuffer("from Role r where 1=1");
		Object[] obj = createQueryParams(vo, hql);
		return queryChannel().queryResultSize(hql.toString(), obj);
	}

	public RoleVO getRoleById(Long id) {
		return toRoleVO(Role.get(id));
	}

	public RoleVO updateRole(RoleVO vo) {
		Role role = Role.get(vo.getId());
		if (role == null) {
			return null;
		}
		{
			role.setDescription(vo.getDescription());
			role.setName(vo.getName());
			if (vo.getStatus() == Role.Status.ENABLED.ordinal()) {
				role.setStatus(Role.Status.ENABLED);
			} else if (vo.getStatus() == Role.Status.DISABLED.ordinal()) {
				role.setStatus(Role.Status.DISABLED);
			}
		}
		return toRoleVO(role.update());

	}

	public Page<RoleVO> pageQueryRole(RoleVO vo, int currentPage, int pageSize) {
		List<Object> params = new ArrayList<Object>();
		String hql = "from Role r where 1=1 ";
		String name = vo != null ? vo.getName() : null;
		if (name != null && (name = name.trim()).length() < 1) {
			hql += "and r.name like ? ";
			params.add("%" + name + "%");
		}
		{
			hql += "order by r.name ";
		}
		Page<Role> page = queryChannel().queryPagedResultByPageNo(hql,
				params.toArray(), currentPage, pageSize);

		List<RoleVO> voList = new ArrayList<RoleVO>();
		List<Role> list = page.getResult();
		for (Role r : list) {
			voList.add(toRoleVO(r));
		}
		return PageUtil.toPage(page, voList);
	}

	public List<RoleVO> queryRole(RoleVO vo) {
		List<Object> params = new ArrayList<Object>();
		String hql = "from Role r where 1=1 ";
		String name = vo != null ? vo.getName() : null;
		if (name != null && (name = name.trim()).length() < 1) {
			hql += "and r.name like ? ";
			params.add("%" + name + "%");
		}
		{
			hql += "order by r.name ";
		}
		List<Role> list = queryChannel().queryResult(hql, params.toArray());

		List<RoleVO> voList = new ArrayList<RoleVO>();
		for (Role r : list) {
			voList.add(toRoleVO(r));
		}
		return voList;
	}

	public List<RoleVO> queryAllByPage(RoleVO vo, int currentPage, int pageSize) {
		StringBuffer hql = new StringBuffer("from Role r where 1=1");
		Object[] obj = createQueryParams(vo, hql);
		List<Role> list = queryChannel().queryResult(hql.toString(), obj);

		List<RoleVO> result = new ArrayList<RoleVO>();
		if (list == null) {
			return result;
		}
		for (Role r : list) {
			result.add(toRoleVO(r));
		}
		return result;

	}

	public void setPermissions(Long id, Long[] funIds) {
		Role role = Role.get(id);
		if (role == null) {
			return;
		}
		if (role.getFunctionEntities() == null) {
			role.setFunctionEntities(new HashSet<FunctionEntity>());
		}

		role.getFunctionEntities().clear();
		funIds = funIds == null ? new Long[0] : funIds;

		for (Long funId : funIds) {
			FunctionEntity entity = FunctionEntity.get(funId);
			if (entity != null) {
				role.getFunctionEntities().add(entity);
			}
		}
		role.update();
		//		try {
		//			ResourceCacheUtil.removeAllResourceCache();
		//		} catch (Exception e) {
		//		}
	}

	public void removePermissions(Long id, Long[] funIds) {
		Role role = Role.get(id);
		if (role == null || role.getFunctionEntities() == null) {
			return;
		}
		funIds = funIds == null ? new Long[0] : funIds;
		for (Long funId : funIds) {
			FunctionEntity entity = FunctionEntity.get(funId);
			if (role.getFunctionEntities().contains(entity)) {
				role.getFunctionEntities().remove(entity);
			}
		}
		role.update();
		//		try {
		//			ResourceCacheUtil.removeAllResourceCache();
		//		} catch (Exception e) {
		//		}
	}

	public void addPermissions(Long id, Long[] funIds) {

		Role role = Role.get(id);
		if (role == null) {
			return;
		}
		// 当前角色拥有的权限
		// 新权限集合
		if (role.getFunctionEntities() == null) {
			role.setFunctionEntities(new HashSet<FunctionEntity>());
		}

		funIds = funIds == null ? new Long[0] : funIds;
		for (Long funId : funIds) {
			FunctionEntity entity = FunctionEntity.get(funId);
			if (!role.getFunctionEntities().contains(entity)) {
				role.getFunctionEntities().add(entity);
			}
		}
		role.update();
		//		try {
		//			ResourceCacheUtil.removeAllResourceCache();
		//		} catch (Exception e) {
		//		}
	}

	public void changeStatus(Long id, int roleStatus) {
		Role role = Role.get(id);
		if (role == null) {
			return;
		}
		if (Status.ENABLED.ordinal() == roleStatus) {
			role.enabled();
		} else {
			role.disabled();
		}

	}

	/**
	 * 构造查询条件
	 * 
	 * @param search
	 * @param hql
	 * @return
	 */
	private Object[] createQueryParams(RoleVO search, StringBuffer hql) {
		List<Object> params = new ArrayList<Object>();
		if (search != null) {
			if (StringUtils.isNotBlank(search.getName())) {
				hql.append(" and r.name like ?");
				params.add("%" + search.getName() + "%");
			}

			if (search.getStatus() == Role.Status.ENABLED.ordinal()) {
				hql.append(" and r.status=?");
				params.add(Role.Status.ENABLED);
			} else if (search.getStatus() == Role.Status.DISABLED.ordinal()) {
				hql.append(" and r.status=?");
				params.add(Role.Status.DISABLED);
			}
		}
		Object[] obj = params.isEmpty() ? new Object[] {} : params.toArray();
		return obj;
	}

	private RoleVO toRoleVO(Role role) {
		return Convertor.po2vo(role, null);
	}

	private Role toRole(RoleVO vo) {
		return Convertor.vo2po(vo, new Role());
	}
}
